Tagged Unions

A tagged union declaration looks just like a C union, except that it you must specify the @tagged qualifier when declaring it. For example:

 @tagged union Foo {
 int i;
 double d;
 char *@fat s;
 };

The primary difference with C unions is that a tagged union includes a hidden tag. The tag indicates which member was last written. So, for example:

 union Foo x;
 x.i = 3;
 x.s = "hello";

causes the hidden tag to first indicate that the i member was written, and then is updated to record that the s member was written.

When you attempt to read a member of a tagged union, a check is done on the hidden tag to ensure that this was the last member written, and thus the union contains a valid object of that member’s type. If some other member was last updated, then a Match_Exception will be thrown.

You can test the hidden tag of a tagged union by using the tagcheck operation. For example:

 void printFoo(union Foo x) {
 if (tagcheck(x.i))
 printf("%d",x.i);
 else if (tagcheck(x.d))
 printf("%g",x.d);
 else if (tagcheck(x.s))
 printf("%s",x.s);
 }

Alternatively, you can use pattern matching (described in the next section) which will ensure that you cover all of the cases properly. For instance, the function above may be rewritten as:

 void printFoo(union Foo x) {
 switch (x) {
 case {.i = i}: printf("%d",i); break;
 case {.d = d}: printf("%g",d); break;
 case {.s = s}: printf("%s",s); break;
 }
 }

If we failed to leave out one of the cases in the pattern match, then the compiler would warn us. This is particularly helpful when you add new variants to a tagged union, for then the compiler pinpoints the spots that you need to update in your code. Therefore, we encourage the use of pattern matching where possible.

AltStyle によって変換されたページ (->オリジナル) /